package authentication;

import java.io.IOException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;

import GUI.MainFrame;

import encryption.Hash;
import encryption.RSA;

import network.CAClient;
import network.Client;
import network.Operations;


public class ClientAuthentication {
	private static final int SIZE_OF_RANDOM_PASSWORD = 10;
	public ClientAuthentication()
	{

	}
	private String generateRandomPassword(){
		SecureRandom randomGenerator = new SecureRandom();

		String password = "";
		for(int i =0 ; i < SIZE_OF_RANDOM_PASSWORD ; i ++){
			int x = randomGenerator.nextInt(26);
			password += (char)(x+'A');
		}
		return password;
	}
	public boolean login(String username, String password) throws Exception{//throws NoSuchAlgorithmException, IOException{
		String keyMod = "";
		String keyExp = "";
		if(MainFrame.getMainFrame().serverPublicKeyExp ==null
				|| MainFrame.getMainFrame().serverPublicKeyMod ==null){


			CAClient ca = new CAClient();
			String key = null;
			try {
				key= ca.CAClientFlow();
			} catch (NoSuchAlgorithmException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
				return false ;
			} catch (IOException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
				return false;
			}
			keyMod = key.split(" ")[0];
			keyExp = key.split(" ")[1];
			MainFrame.getMainFrame().serverPublicKeyExp = keyExp;
			MainFrame.getMainFrame().serverPublicKeyMod  = keyMod;
		}else{
			keyMod = MainFrame.getMainFrame().serverPublicKeyMod;
			keyExp = MainFrame.getMainFrame().serverPublicKeyExp;
		}

		sendUsername(Operations.LOGIN+" "+username);
		String receivedmsg = Client.client.receiveMessage();
		if(receivedmsg.equals(Operations.TOO_MANY_FAILED_ATTEMPS + "")){
			throw new Exception("too many failed attempts");
		}
		if(receivedmsg.equals(Operations.LOGIN_FAILED + "")){
			return false;
		}
		String [] received = receivedmsg.split(" ");
		String hashName;
		String outerHashName;
		String salt;
		String random;
		try{
			if(received.length==4){
				hashName = received[0];
				outerHashName = received[1];
				salt = received[2];
				random = received[3];
			}
			else{
				return false;
			}
			String randomPassword = generateRandomPassword();
			System.out.println(Hash.getHashSalt(password, Hash.base64ToByte(salt), hashName) + " hashed "+password+" "+salt+" "+ hashName);
			String dblHashed = Hash.getFastHashSalt(Hash.getHashSalt(password, Hash.base64ToByte(salt), hashName),Hash.base64ToByte(random),outerHashName);
			//encrypt by RSA
			String message = random+" "+ dblHashed + " " + randomPassword;
			byte[] encryptedMessage = new RSA().rsaEncryptToBytes(message,keyMod , keyExp);
			Client.client.sendRSAMessage(encryptedMessage);
			String fromServer = Client.client.receiveMessage();
			Client.client.setRandomPassword(randomPassword);
			return fromServer.equals(""+Operations.LOGIN_COMPLETE);
		}catch(Exception e){
			return false;
		}
	}

	public int getUserID(String email){
		Client.client.sendMessage(Operations.GET_ID+" "+email);
		String fromServer = Client.client.receiveMessage();
		System.out.println("Message from clitn "+fromServer.split(" ")[1]);
		try{
			return Integer.parseInt(fromServer.split(" ")[1]);
		}
		catch(NullPointerException e){
			return -1;
		}
		catch(NumberFormatException e){
			return -1;
		}
	}

	public void sendUsername(String username){
		//send the username to the server
		Client.client.sendMessage(username);
	}
}
